#include "users_login.h"

#include "struct_tlv.h"

#include "log.h"

int usersLogin(userOpInfo_t *useropinfo){
    MYSQL *conn = useropinfo->mysql;
    int netfd = useropinfo->netfd;
    tlvPacket_t packet;
    memset(&packet, 0, sizeof(tlvPacket_t));

    int ret;
    commandType_t type;
    char userName[1024] = {0};
    int userDeleteFlag;//已存在用户的is_deleted
    char query[4096];//mysql命令字符串
    MYSQL_RES *res;
    MYSQL_ROW row;//获取的行值
    char encryptedPassWord[1024] = {0};//定义密文

    while(1){
        //接收用户名和type
        ret = recv(netfd, &packet.type, sizeof(packet.type), MSG_WAITALL);
        if(ret == 0){
            return -1;
        }
        type = packet.type;
        ret = recv(netfd, &packet.length, sizeof(packet.length), MSG_WAITALL);
        if(ret == 0){
            return -1;
        }
        ret = recv(netfd, packet.value, packet.length, MSG_WAITALL);
        if(ret == 0){
            return -1;
        }
        memcpy(userName,packet.value,packet.length);

        //注册业务退出循环
        if(type == REGISTER){
            break;
        }

        //在用户表中查询用户是否存在
        memset(query,0,sizeof(query));
        int existsUser = 1;//1用户默认存在
        snprintf(query,sizeof(query),"SELECT is_deleted FROM user_info WHERE username = '%s'", userName);

        //执行查询
        if(mysql_query(conn,query)){
            fprintf(stderr,"mysql_query failed:%s\n",mysql_error(conn));
            return -1;
        }

        //获取结果  
        res = mysql_store_result(conn);
        if(!res){
            if(mysql_error(conn)){
                fprintf(stderr, "获取结果失败：%s\n",mysql_error(conn));
                return -1;
            }else{
                printf("不是select\n");
            }
        }
        else{
            row = mysql_fetch_row(res);
            if(row != NULL){
                userDeleteFlag = atoi(row[0]);//为一存在已删用户
                if(userDeleteFlag == 1){
                    existsUser = 0;
                }else{
                    existsUser = 1;
                }

            }
            else{
                existsUser = 0;
                fprintf(stderr,"警告: user不存在为空\n");
            }
        }

        mysql_free_result(res);

        //给client发送是否存在该用户
        send(netfd,&existsUser,sizeof(int),MSG_NOSIGNAL);
        //printf("existsUser = %d\n",existsUser);
        if(existsUser == 1) break;
    }

    //返回给调用者所需参数,修改useropinfo结构体
    memcpy(useropinfo->userName,userName,sizeof(useropinfo->userName));//返回用户名

    char*salt;
    char output[CRYPT_GENSALT_OUTPUT_SIZE] = {0};
    if(type == REGISTER){
        //生成salt
        salt = crypt_gensalt_r("$y$",0,NULL,0,output,sizeof(output));
        ERROR_CHECK(salt,NULL,"crypt_gensalt_r");
    }
    else{
        //获取salt
         memset(query,0,sizeof(query));
         snprintf(query,sizeof(query),"SELECT salt FROM user_info WHERE username = '%s'",userName);
         if(mysql_query(conn,query)){
            fprintf(stderr,"查找失败：%s\n",mysql_error(conn));
            mysql_close(conn);
            return -1;
        }
        res = mysql_store_result(conn);
        if(!res){
            fprintf(stderr, "row获取结果失败: %s\n",mysql_error(conn));
        }
        row = mysql_fetch_row(res);
        if(!row){
            fprintf(stderr, "row获取结果失败: %s\n",mysql_error(conn));
        }
        memcpy(output,row[0],sizeof(output));
        salt = output;
    }
    //发送salt
    memset(&packet,0,sizeof(packet));
    packet.length = strlen(salt)+1;
    memcpy(packet.value,salt,packet.length);
    send(netfd,&packet,sizeof(packet.type)
         +sizeof(packet.length)+packet.length,MSG_NOSIGNAL);

    //注册
    if(type == REGISTER){
        //接收密文
        ret = recv(netfd,&packet.type,sizeof(packet.type),MSG_WAITALL);
        if(ret == 0){
            printf("ret = 0, client已退出！\n");
            return -1;
        }
        ret = recv(netfd,&packet.length,sizeof(packet.length),MSG_WAITALL);
        if(ret == 0){
            printf("ret = 0, client已退出！\n");
            return -1;
        }
        ret = recv(netfd,packet.value,packet.length,MSG_WAITALL);
        if(ret == 0){
            printf("ret = 0, client已退出！\n");
            return -1;
        }
        memcpy(encryptedPassWord,packet.value,packet.length);

        int success = 1;
        //存在delete的同名用户，更改信息注册
        if(userDeleteFlag == 1){
            snprintf(query,sizeof(query),"UPDATE user_info SET is_deleted = 0 WHERE username='%s'",userName);
            if(mysql_query(conn,query)){
                success = -1;
                send(netfd,&success,sizeof(int),MSG_NOSIGNAL);
                fprintf(stderr,"插入失败：%s\n",mysql_error(conn));
                mysql_close(conn);
                return -1;
            }
            int result = mysql_affected_rows(conn);
            if(result == -1){
                success = -1;
                send(netfd,&success,sizeof(int),MSG_NOSIGNAL);
                fprintf(stderr,"set错误: %s\n",mysql_error(conn));
                return -1;
            }
            printf("新用户成功修改用户表\n");
            send(netfd,&success,sizeof(int),MSG_NOSIGNAL);
        }
        //新用户插入用户表
        else
        {
            int is_deleted = 0;
            memset(query,0,sizeof(query));
            snprintf(query,sizeof(query),
                     "INSERT INTO user_info (username,salt,encrypted_password,is_deleted)"
                     "VALUES('%s','%s','%s','%d')",
                     userName,salt,encryptedPassWord,is_deleted);

            //执行查询语句
            if(mysql_query(conn,query)){
                success = -1;
                send(netfd,&success,sizeof(int),MSG_NOSIGNAL);//发送注册失败的信息
                fprintf(stderr,"插入失败：%s\n",mysql_error(conn));
                mysql_close(conn);
                return -1;
            }
            printf("新用户成功插入用户表\n");
            send(netfd,&success,sizeof(int),MSG_NOSIGNAL);
        }
        //注册初始化文件表
        memset(query,0,sizeof(query));
        snprintf(query,sizeof(query),
                 "INSERT INTO file_info (username)"
                 "VALUES('%s')",
                 userName);
        if(mysql_query(conn,query)){
            fprintf(stderr,"插入失败：%s\n",mysql_error(conn));
            mysql_close(conn);
            return -1; 
        }   
        useropinfo->ID = (int)mysql_insert_id(conn);

        printf("注册成功\n");
    }
    //登录
    else
    {
        //用户表查找密文
        char encryptedPassWordExist[1024] = {0};
        memset(query,0,sizeof(query));
        snprintf(query,sizeof(query),"SELECT encrypted_passWord FROM user_info WHERE username = '%s'",userName);
        if(mysql_query(conn,query)){
            fprintf(stderr,"查找失败：%s\n",mysql_error(conn));
            mysql_close(conn);
            return -1;
        }
        res = mysql_store_result(conn);
        row = mysql_fetch_row(res);
        if(!row){
            fprintf(stderr, "row获取结果失败: %s\n",mysql_error(conn));
        }

        while(1){
            //接收密文
            memset(encryptedPassWord,0,sizeof(encryptedPassWord));
            ret = recv(netfd,&packet.type,sizeof(packet.type),MSG_WAITALL);
            if(ret == 0){
                printf("ret = 0, client已退出！\n");
                return -1;
            }
            ret = recv(netfd,&packet.length,sizeof(packet.length),MSG_WAITALL);
            if(ret == 0){
                printf("ret = 0, client已退出！\n");
                return -1;
            }
            ret = recv(netfd,packet.value,packet.length,MSG_WAITALL);
            if(ret == 0){
                printf("ret = 0, client已退出！\n");
                return -1;
            }
            memcpy(encryptedPassWord,packet.value,packet.length);

            memcpy(encryptedPassWordExist,row[0],strlen(row[0])+2);

            //找密文
            int loginFlag;
            if((strcmp(encryptedPassWordExist,encryptedPassWord) == 0)){
                loginFlag = 1;
            }else{
                loginFlag = -1;
            }
            send(netfd,&loginFlag,sizeof(int),MSG_NOSIGNAL);//发送登录密码是否正确
            if(loginFlag == 1) break;
        }
        //返回文件表的parentID
        memset(query,0,sizeof(query));
        snprintf(query,sizeof(query),"SELECT id FROM file_info WHERE username = '%s'",userName);
        if(mysql_query(conn,query)){
            fprintf(stderr,"查找失败：%s\n",mysql_error(conn));
            mysql_close(conn);
            return -1;
        }
        res = mysql_store_result(conn);
        row = mysql_fetch_row(res);
        if(!row){
            fprintf(stderr, "row获取结果失败: %s\n",mysql_error(conn));
        }
        int id;
        id = atoi(row[0]);
        useropinfo->ID = id;
        printf("成功登录\n");

    }


    return 1;
}
